/**
 * Error handling utilities for frontend
 */

/**
 * Show user-friendly error message
 * @param {Error|string} error - Error object or message
 * @param {string} defaultMessage - Default message if error is unknown
 */
function showError(error, defaultMessage = '操作失败，请稍后重试') {
  let message = defaultMessage;
  
  if (typeof error === 'string') {
    message = error;
  } else if (error && error.message) {
    message = error.message;
  } else if (error && error.error && error.error.message) {
    // Backend error response format
    message = error.error.message;
  }
  
  wx.showToast({
    title: message,
    icon: 'none',
    duration: 3000
  });
}

/**
 * Show loading indicator
 * @param {string} title - Loading message
 */
function showLoading(title = '加载中...') {
  wx.showLoading({
    title: title,
    mask: true
  });
}

/**
 * Hide loading indicator
 */
function hideLoading() {
  wx.hideLoading();
}

/**
 * Make API request with retry and error handling
 * @param {Object} options - Request options
 * @param {string} options.url - API endpoint
 * @param {string} options.method - HTTP method
 * @param {Object} options.data - Request data
 * @param {number} options.maxRetries - Maximum retry attempts (default: 3)
 * @param {number} options.retryDelay - Initial retry delay in ms (default: 1000)
 * @param {boolean} options.showLoading - Show loading indicator (default: true)
 * @param {string} options.loadingText - Loading text
 * @returns {Promise} - Promise resolving to response data
 */
function requestWithRetry(options) {
  const {
    url,
    method = 'GET',
    data = {},
    maxRetries = 3,
    retryDelay = 1000,
    showLoadingIndicator = true,
    loadingText = '加载中...'
  } = options;
  
  if (showLoadingIndicator) {
    showLoading(loadingText);
  }
  
  return new Promise((resolve, reject) => {
    let attempt = 0;
    
    function makeRequest() {
      attempt++;
      
      wx.request({
        url: url,
        method: method,
        data: data,
        header: {
          'content-type': 'application/json',
          'Authorization': wx.getStorageSync('token') || ''
        },
        success: (res) => {
          if (showLoadingIndicator) {
            hideLoading();
          }
          
          // Check if response indicates success
          if (res.statusCode === 200) {
            // Check backend success flag
            if (res.data && res.data.success === false) {
              // Backend returned error
              const errorMsg = res.data.error?.message || '请求失败';
              reject(new Error(errorMsg));
            } else {
              resolve(res.data);
            }
          } else if (res.statusCode >= 500 && attempt < maxRetries) {
            // Server error, retry
            console.warn(`Request failed (attempt ${attempt}/${maxRetries}), retrying...`);
            setTimeout(() => {
              makeRequest();
            }, retryDelay * attempt); // Exponential backoff
          } else {
            // Other errors
            const errorMsg = getErrorMessage(res.statusCode);
            reject(new Error(errorMsg));
          }
        },
        fail: (err) => {
          console.error('Request failed:', err);
          
          if (attempt < maxRetries) {
            // Network error, retry
            console.warn(`Request failed (attempt ${attempt}/${maxRetries}), retrying...`);
            setTimeout(() => {
              makeRequest();
            }, retryDelay * attempt);
          } else {
            if (showLoadingIndicator) {
              hideLoading();
            }
            reject(new Error('网络连接失败，请检查您的网络设置'));
          }
        }
      });
    }
    
    makeRequest();
  });
}

/**
 * Get user-friendly error message based on status code
 * @param {number} statusCode - HTTP status code
 * @returns {string} - Error message
 */
function getErrorMessage(statusCode) {
  const errorMessages = {
    400: '请求参数错误',
    401: '认证失败，请重新登录',
    403: '没有访问权限',
    404: '请求的资源不存在',
    429: '请求过于频繁，请稍后重试',
    500: '服务器错误，请稍后重试',
    502: '服务暂时不可用',
    503: '服务暂时不可用'
  };
  
  return errorMessages[statusCode] || '请求失败，请稍后重试';
}

/**
 * Handle network error with user-friendly message
 * @param {Error} error - Error object
 * @param {string} context - Context of the error (e.g., '获取天气信息')
 */
function handleNetworkError(error, context = '操作') {
  console.error(`${context}失败:`, error);
  
  let message = `${context}失败`;
  
  if (error && error.message) {
    message = error.message;
  }
  
  showError(message);
}

/**
 * Retry function with exponential backoff
 * @param {Function} fn - Function to retry
 * @param {number} maxRetries - Maximum retry attempts
 * @param {number} delay - Initial delay in ms
 * @returns {Promise} - Promise resolving to function result
 */
async function retryWithBackoff(fn, maxRetries = 3, delay = 1000) {
  let lastError;
  
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await fn();
    } catch (error) {
      lastError = error;
      
      if (attempt < maxRetries - 1) {
        console.warn(`Attempt ${attempt + 1} failed, retrying in ${delay}ms...`);
        await new Promise(resolve => setTimeout(resolve, delay));
        delay *= 2; // Exponential backoff
      }
    }
  }
  
  throw lastError;
}

module.exports = {
  showError,
  showLoading,
  hideLoading,
  requestWithRetry,
  getErrorMessage,
  handleNetworkError,
  retryWithBackoff
};
